using DevExpress.Xpo;
using EasyXaf.EntityDesigner.Editors.DetailViewEditors.Models;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;

namespace EasyXaf.EntityDesigner.Editors.DetailViewEditors;

public partial class DetailViewEditorRenderer : IAsyncDisposable
{
    private readonly string EditorId = $"id-{Guid.NewGuid()}";

    private DotNetObjectReference<DetailViewEditorRenderer> DotNetObjectRef { get; set; }

    private IJSObjectReference JsModule { get; set; }

    private LayoutDesigner LayoutDesigner { get; set; }

    private string SourceCode
    {
        get => Model.View.ViewLayout;
        set
        {
            Model.View.ViewLayout = value;
            ((UnitOfWork)Model.View.Session).CommitChanges();
        }
    }

    [Inject]
    private IJSRuntime JSRuntime { get; set; }

    [Parameter]
    public DetailViewEditorModel Model { get; set; }

    private void OnLayoutChanged()
    {
        SourceCode = LayoutDesigner.ToXml();
    }

    private void OnSourceCodeChanged(string sourceCode)
    {
        if (string.IsNullOrWhiteSpace(sourceCode))
        {
            sourceCode = "<v></v>";
        }

        SourceCode = sourceCode;
        LayoutDesigner.FromXml(sourceCode);
    }

    protected override void OnInitialized()
    {
        base.OnInitialized();

        LayoutDesigner = new LayoutDesigner(Model.View.Entity);

        if (!string.IsNullOrWhiteSpace(Model.View.ViewLayout))
        {
            LayoutDesigner.FromXml(Model.View.ViewLayout);
        }
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await base.OnAfterRenderAsync(firstRender);

        if (firstRender)
        {
            var jsModuleFile = "/Editors/DetailViewEditors/DetailViewEditorRenderer.razor.js";
            JsModule = await JSRuntime.InvokeAsync<IJSObjectReference>("import", jsModuleFile);
            DotNetObjectRef = DotNetObjectReference.Create(this);
            await JsModule.InvokeVoidAsync("init", EditorId, DotNetObjectRef);
        }
    }

    public async ValueTask DisposeAsync()
    {
        if (JsModule != null)
        {
            await JsModule.DisposeAsync();
            JsModule = null;
        }

        DotNetObjectRef?.Dispose();
        DotNetObjectRef = null;

        GC.SuppressFinalize(this);
    }
}